﻿using Microsoft.Extensions.DependencyInjection.Extensions;
using System.Collections.Concurrent;

namespace XxlJobDotNetCore.Extension
{
    public static class ServiceCollectionExtensions
    {
        private static readonly ConcurrentDictionary<string, char> s_RegisteredModels = new ConcurrentDictionary<string, char>();

        public static IServiceCollection ReplaceConfiguration(this IServiceCollection services, IConfiguration configuration)
        {
            return services.Replace(ServiceDescriptor.Singleton(configuration));
        }

        public static IConfiguration GetConfiguration(this IServiceCollection services)
        {
            HostBuilderContext singletonInstanceOrNull = services.GetSingletonInstanceOrNull<HostBuilderContext>();
            if (singletonInstanceOrNull?.Configuration != null)
            {
                IConfigurationRoot configurationRoot = singletonInstanceOrNull.Configuration as IConfigurationRoot;
                if (configurationRoot != null)
                {
                    return configurationRoot;
                }
            }

            return services.GetSingletonInstance<IConfiguration>();
        }
        internal static T? GetSingletonInstanceOrNull<T>(this IServiceCollection services) where T : class
        {
            object obj = services.FirstOrDefault((ServiceDescriptor d) => d.ServiceType == typeof(T))?.ImplementationInstance;
            if (obj == null)
            {
                return null;
            }

            return (T)obj;
        }

        internal static T GetSingletonInstance<T>(this IServiceCollection services) where T : class
        {
            return services.GetSingletonInstanceOrNull<T>() ?? throw new InvalidOperationException("Could not find singleton service: " + typeof(T).AssemblyQualifiedName);
        }

    }
}
